﻿import sys, os
import yaml
import random

STYLEFILE = 'style.yaml'
CFGFILE = 'cfg.yaml'
CFGNAMEFILE = 'cfg_name.yaml'
# 数据类型:
# choice: 一堆值中选择 
# range: 整数范围内选择
DEFAULTNAME = {
        'first_name': {'type': 'str', 'value': ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何', '吕', '施', '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹', '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛', '奚', '范', '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '俞', '任', '袁', '柳', '酆', '鲍', '史', '唐', '费', '廉', '岑', '薛', '雷', '贺', '倪', '汤', '滕', '殷', '罗', '毕', '郝', '邬', '安', '常', '乐', '于', '时', '傅', '皮', '卞', '齐', '康', '伍', '余', '元', '卜', '顾', '孟', '平', '黄', '和', '穆', '萧', '尹', '姚', '邵', '湛', '汪', '祁', '毛', '禹', '狄', '米', '贝', '明', '臧', '计', '伏', '成', '戴', '谈', '宋', '茅', '庞', '熊', '纪', '舒', '屈', '项', '祝', '董', '梁', '杜', '阮', '蓝', '闵', '席', '季', '麻', '强', '贾', '路', '娄', '危', '江', '童', '颜', '郭', '梅', '盛', '林', '刁', '锺', '徐', '丘', '骆', '高', '夏', '蔡', '田', '樊', '胡', '凌', '霍', '虞', '万', '支', '柯', '昝', '管', '卢', '莫', '经', '房', '裘', '缪', '干', '解', '应', '宗', '丁', '宣', '贲', '邓', '郁', '单', '杭', '洪', '包', '诸', '左', '石', '崔', '吉', '钮', '龚', '程', '嵇', '邢', '滑', '裴', '陆', '荣', '翁', '荀', '羊', '於', '惠', '甄', '麹', '家', '封', '芮', '羿', '储', '靳', '汲', '邴', '糜', '松', '井', '段', '富', '巫', '乌', '焦', '巴', '弓', '牧', '隗', '山', '谷', '车', '侯', '宓', '蓬', '全', '郗', '班', '仰', '秋', '仲', '伊', '宫', '甯', '仇', '栾', '暴', '甘', '钭', '厉', '戎', '祖', '武', '符', '刘', '景', '詹', '束', '龙', '叶', '幸', '司', '韶', '郜', '黎', '蓟', '薄', '印', '宿', '白', '怀', '蒲', '邰', '从', '鄂', '索', '咸', '籍', '赖', '卓', '蔺', '屠', '蒙', '池', '乔', '阴', '鬱', '胥', '能', '苍', '双', '闻', '莘', '党', '翟', '谭', '贡', '劳', '逄', '姬', '申', '扶', '堵', '冉', '宰', '郦', '雍', '郤', '璩', '桑', '桂', '濮', '牛', '寿', '通', '边', '扈', '燕', '冀', '郏', '浦', '尚', '农', '温', '别', '庄', '晏', '柴', '瞿', '阎', '充', '慕', '连', '茹', '习', '宦', '艾', '鱼', '容', '向', '古', '易', '慎', '戈', '廖', '庾', '终', '暨', '居', '衡', '步', '都', '耿', '满', '弘', '匡', '国', '文', '寇', '广', '禄', '阙', '东', '欧', '殳', '沃', '利', '蔚', '越', '夔', '隆', '师', '巩', '厍', '聂', '晁', '勾', '敖', '融', '冷', '訾', '辛', '阚', '那', '简', '饶', '空', '曾', '毋', '沙', '乜', '养', '鞠', '须', '丰', '巢', '关', '蒯', '相', '查', '后', '荆', '红', '游', '竺', '权', '逯', '盖', '益', '桓', '公', '万俟', '司马', '上官', '欧阳', '夏侯', '诸葛', '闻人', '东方', '赫连', '皇甫', '尉迟', '公羊', '澹台', '公冶', '宗政', '濮阳', '淳于', '单于', '太叔', '申屠', '公孙', '仲孙', '轩辕', '令狐', '锺离', '宇文', '长孙', '慕容', '鲜于', '闾丘', '司徒', '司空', '亓官', '司寇', '仉', '督', '子车', '颛孙', '端木', '巫马', '公西', '漆雕', '乐正', '壤驷', '公良', '拓跋', '夹谷', '宰父', '穀梁', '晋', '楚', '闫', '法', '汝', '鄢', '涂', '钦', '段干', '百里', '东郭', '南门', '呼延', '归海', '羊舌', '微生', '岳', '帅', '缑', '亢', '况', '後', '有', '琴', '梁丘', '左丘', '东门', '西门', '商', '牟', '佘', '佴', '伯', '赏', '南宫', '墨', '哈', '谯', '笪', '年', '爱', '阳', '佟', '第五', '言', '福']},
        'mid_name': {'type': 'str', 'value': [x for x in '中笑贝凯歌易仁器义礼智信友上都卡被好无九加电金马钰玉忠孝']},
        'boy_name': {'type': 'str', 'value': [x for x in '伟刚勇毅俊峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩中茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛雄琛钧冠策腾楠榕风航弘']},
        'girl_name': {'type': 'str', 'value': [x for x in '秀娟英华慧巧美娜静淑惠珠翠雅芝玉萍红娥玲芬芳燕彩春菊兰凤洁梅琳素云莲真环雪荣爱妹霞香月莺媛艳瑞凡佳嘉琼勤珍贞莉桂娣叶璧璐娅琦晶妍茜秋珊莎锦黛青倩婷姣婉娴瑾颖露瑶怡婵雁蓓纨仪荷丹蓉眉君琴蕊薇菁梦岚苑婕馨瑗琰韵融园艺咏卿聪澜纯毓悦昭冰爽琬茗羽希宁欣飘育滢馥筠柔竹霭凝晓欢霄枫芸菲寒伊亚宜可姬舒影荔枝思丽']},
        }

DEFAULTCFG = {
        '人族': {
            'age': {'type': 'range', 'name': '年龄', 'value': [10, 40]},
            'sex': {'type': 'choice', 'name': '性别', 'value': ['男', '女']},
            'eye': {'type': 'str', 'name': '眼睛', 'value': ['丹凤眼', '桃花眼']},
            'hair_color': {'type': 'str', 'name': '发色', 'value': [x for x in '赤橙红绿青蓝紫']},
            'layout': {'type': 'layout', 'value': ['age', 'sex', 'eye', 'hair_color']}
            },
        '精灵族': {
            'age': {'type': 'range', 'name': '年龄', 'value': [10, 500]},
            'sex': {'type': 'choice', 'name': '性别', 'value': ['男', '女']},
            'eye': {'type': 'choice', 'name': '眼睛', 'value': ['丹凤眼', '桃花眼']},
            'face': {'type': 'choice', 'name': '脸', 'value': ['国字脸', '瓜子脸', '锥子脸', '圆脸']},
            'hair_color': {'type': 'str', 'name': '发色', 'value': [x for x in '赤橙红绿青蓝紫']},
            'layout': {'type': 'layout', 'value': ['age', 'sex', 'eye', 'face', 'hair_color']}
            },
        '龙族': {
            'age': {'type': 'range', 'name': '年龄', 'value': [500, 1000]},
            'sex': {'type': 'choice', 'name': '性别', 'value': ['男', '女']},
            'eye': {'type': 'choice', 'name': '眼睛', 'value': ['竖瞳', '圆瞳', '黑瞳', '白瞳']},
            'type': {'type': 'choice', 'name': '类别', 'value': ['红龙', '绿龙', '黑龙', '蓝龙', '黄龙', '虚空龙', '精灵龙', '骨龙']},
            'layout': {'type': 'layout', 'value': ['age', 'sex', 'eye', 'type']}
            }
        }

class RoleMaker():
    def __init__(self, cfg=None, nameCfg=None):
        self.cfg = cfg
        self.nameCfg = nameCfg
        self.loadCfg(False)
        self.saveCfg()
        self.roleType = list(self.cfg.keys())[0]
        self.table = {}
        self.reset(self.roleType)

    def loadCfg(self, isForce):
        if isForce or self.cfg is None:
            if os.path.isfile(CFGFILE):
                with open(CFGFILE, 'r', encoding='utf-8') as fp:
                    self.cfg = yaml.load(fp, Loader=yaml.FullLoader)

        if isForce or self.nameCfg is None:
            if os.path.isfile(CFGNAMEFILE):
                with open(CFGNAMEFILE, 'r', encoding='utf-8') as fp:
                    self.nameCfg = yaml.load(fp, Loader=yaml.FullLoader)

    def saveCfg(self):
        if self.cfg is None:
            self.cfg = DEFAULTCFG
            with open(CFGFILE, 'w', encoding='utf-8') as fp:
                yaml.dump(self.cfg, fp, allow_unicode=True)

        if self.nameCfg is None:
            self.nameCfg = DEFAULTNAME
            with open(CFGNAMEFILE, 'w', encoding='utf-8') as fp:
                yaml.dump(self.nameCfg, fp, allow_unicode=True)

    def genTable(self, cfg, dctTable={}):
        lstLayout = cfg['layout']['value']

        if self.table == {}: # 如果table为空则先初始化table
            self.table['name'] = ['姓名', None, False, 'str']
            for key in lstLayout:
                self.table[key] = [cfg[key]['name'], None, False, cfg[key]['type']]

        for key in lstLayout:
            if dctTable.get(key) is not None: # 如果有传入值则用传入值
                self.table[key][1] = dctTable.get(key)
            else:
                isLock = self.table[key][2] 
                if not isLock: # 没锁定则给新值
                    self.table[key][1] = self.genAttr(key, cfg)
        isLock = False
        if self.table.get('name') is not None:
            isLock = self.table['name'][2]
        if not isLock:
            self.table['name'][1] = self.genName(self.table['sex'][1]) # 设置姓名

    def genAttr(self, key, cfg):
        attrType = cfg[key]['type']
        attrValue = cfg[key]['value']
        value = None
        if attrType == 'str':
            value = attrValue[random.randint(0, len(attrValue) - 1)]
        elif attrType == 'range':
            value = str(random.randint(attrValue[0], attrValue[1]))
        elif attrType == 'choice':
            value = attrValue[random.randint(0, len(attrValue) - 1)]
        return value

    def genName(self, sex):
        firstName = self.genAttr('first_name', self.nameCfg)

        midName = ''
        if random.random() > 0.5:
            midName = self.genAttr('mid_name', self.nameCfg)

        lastName = ''
        if sex == '男':
            lastName = self.genAttr('boy_name', self.nameCfg)
        elif sex == '女':
            lastName = self.genAttr('girl_name', self.nameCfg)

        return firstName + midName + lastName

    def reload(self):
        self.loadCfg(True)
        self.reset()

    def reset(self, roleType=None):
        self.table.clear()
        if self.cfg.get(roleType) is not None:
            self.roleType = roleType
            self.genTable(self.cfg[self.roleType])
        else:
            self.roleType = list(self.cfg.keys())[0]
            self.genTable(self.cfg[self.roleType])

    def refresh(self):
        dctTable = {}
        for key, val in self.table.items():
            isLock = val[2] 
            if not isLock: continue
            dctTable[key] = val[1]
        self.genTable(self.cfg[self.roleType], dctTable)

    def save(self):
        if len(self.table) > 0:
            name = self.table['name'][1]
            with open(name + '.txt', 'w') as fp:
                for key, val in self.table.items():
                    k, v, _, t = val
                    fp.write('{}: {}\n'.format(k, v))

if __name__=='__main__':
    cfg = None
    if os.path.isfile(CFGFILE):
        with open(CFGFILE, 'r', encoding='utf-8') as fp:
            cfg = yaml.load(fp, Loader=yaml.FullLoader)

    nameCfg = None
    if os.path.isfile(CFGNAMEFILE):
        with open(CFGNAMEFILE, 'r', encoding='utf-8') as fp:
            nameCfg = yaml.load(fp, Loader=yaml.FullLoader)

    roleMaker = RoleMaker(cfg, nameCfg)
    print(roleMaker.table)
